﻿// -----------------------------------------------------------------------------
// 园丁,是个很简单的管理系统
//  gitee:https://gitee.com/hgflydream/Gardener 
//  issues:https://gitee.com/hgflydream/Gardener/issues 
// -----------------------------------------------------------------------------

using Furion.DatabaseAccessor;
using Gardener.Application.Dtos;
using Gardener.Core.Entites;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Threading.Tasks;
using Gardener.Common;
using System.Linq.Expressions;
using Furion.FriendlyException;
using Gardener.Enums;
using Gardener.Core;
using Gardener.Application.Interfaces;
using Furion;

namespace Gardener.Application
{
    /// <summary>
    /// 用户服务
    /// </summary>
    [ApiDescriptionSettings("UserAuthorizationServices")]
    public class ShieldService : LockExtendServiceBase<Shield, ShieldDto>, IShieldService
    {
        private readonly IRepository<Shield> _shieldRepository;
        private readonly IRepository<Car> _carRepository;
        /// <summary>
        /// 用户服务
        /// </summary>
        /// <param name="shieldRepository"></param>
        public ShieldService(
            IRepository<Shield> shieldRepository,
            IRepository<Car> carRepository) : base(shieldRepository)
        {
            _carRepository = carRepository;
            _shieldRepository = shieldRepository;
        }

        /// <summary>
        /// 搜索用户
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Dtos.PagedList<ShieldDto>> Search([FromQuery] string name, int pageIndex = 1, int pageSize = 10)
        {
            var shields = _shieldRepository
              .Where(u => u.IsDeleted == false)
              .Where(!string.IsNullOrEmpty(name), u => u.ShieldNumber.Contains(name))
              .OrderByDescending(x => x.CreatedTime)
              .Select(u => u.Adapt<ShieldDto>());
            var pageList = await shields.ToPagedListAsync(pageIndex, pageSize);
            
            return pageList;

        }
        /// <summary>
        /// 更新一条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override async Task<bool> Update(ShieldDto input)
        {
            var newShield = input.Adapt<Shield>();
            newShield.UpdatedTime = DateTimeOffset.Now;
            if (_shieldRepository.Any(x => x.IsDeleted == false && x.Id != newShield.Id 
                && newShield.ShieldNumber.Contains(x.ShieldNumber), false))
            {
                throw Oops.Oh(ExceptionCode.SHIELD_NUMBER_REPEAT);
            }

            List<Expression<Func<Shield, object>>> exclude = new List<Expression<Func<Shield, object>>>()
            {
                x=>x.CreatedTime
            };

            //更新旧车辆信息 删除限制类型before时 更新车辆放行
            var shield = await _shieldRepository.FindAsync(input.Id);
            if (shield.ShieldNumber == newShield.ShieldNumber)
            {
                if (shield.ShieldType == ShieldType.After && newShield.ShieldType != ShieldType.After)
                {
                    //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                    var cars = _carRepository
                      .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.IsRelease == true && c.CarNumber.Contains(shield.ShieldNumber))
                      .AsNoTracking()   //取消attached
                      .Select(u => u.Adapt<Car>());

                    foreach (Car car in cars)
                    {
                        car.IsRelease = false;
                        car.UpdatedTime = DateTimeOffset.Now;
                        await _carRepository.UpdateAsync(car);
                    }
                }

                //更新新车辆信息 新增限制类型before时 更新车辆放行
                if (shield.ShieldType != ShieldType.After && newShield.ShieldType == ShieldType.After)
                {
                    //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                    var cars = _carRepository
                      .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.IsRelease == false && c.CarNumber.Contains(newShield.ShieldNumber))
                      .AsNoTracking()   //取消attached
                      .Select(u => u.Adapt<Car>());

                    foreach (Car car in cars)
                    {
                        car.IsRelease = true;
                        car.UpdatedTime = DateTimeOffset.Now;
                        await _carRepository.UpdateAsync(car);
                    }
                }
            }
            else
            {
                if (shield.ShieldType != ShieldType.After)
                {
                    //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                    var cars = _carRepository
                      .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.IsRelease == false && c.CarNumber.Contains(shield.ShieldNumber))
                      .AsNoTracking()   //取消attached
                      .Select(u => u.Adapt<Car>());

                    foreach (Car car in cars)
                    {
                        car.IsRelease = true;
                        car.UpdatedTime = DateTimeOffset.Now;
                        await _carRepository.UpdateAsync(car);
                    }
                }

                //更新新车辆信息 新增限制类型before时 更新车辆放行
                if (newShield.ShieldType != ShieldType.After)
                {
                    //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                    var cars = _carRepository
                      .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.IsRelease == true && c.CarNumber.Contains(newShield.ShieldNumber))
                      .AsNoTracking()   //取消attached
                      .Select(u => u.Adapt<Car>());

                    foreach (Car car in cars)
                    {
                        car.IsRelease = false;
                        car.UpdatedTime = DateTimeOffset.Now;
                        await _carRepository.UpdateAsync(car);
                    }
                }
            }

            //更新
            shield.ShieldNumber = newShield.ShieldNumber;
            shield.ShieldType = newShield.ShieldType;
            shield.UpdatedTime = newShield.UpdatedTime;
            await _shieldRepository.UpdateExcludeAsync(shield, new[] { "CreatedTime" });

            return true;
        }
        /// <summary>
        /// 新增一条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override async Task<ShieldDto> Insert(ShieldDto input)
        {
            //判断 未删除 && 种类为新申请或all && 相互包含
            if (_shieldRepository.Any(x => x.IsDeleted == false && x.ShieldType != ShieldType.Before && input.ShieldNumber.Contains(x.ShieldNumber), false))
            {
                throw Oops.Oh(ExceptionCode.SHIELD_NUMBER_REPEAT);
            }

            //新增限制类型before时 更新车辆放行
            if (input.ShieldType != ShieldType.After)
            {
                //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                var cars = _carRepository
                  .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.CarNumber.Contains(input.ShieldNumber))
                  .AsNoTracking()   //取消attached
                  .Select(u => u.Adapt<Car>());

                foreach (Car car in cars)
                {
                    car.IsRelease = false;
                    car.UpdatedTime = DateTimeOffset.Now;
                    await _carRepository.UpdateAsync(car);
                }
            }

            //提交人
            var user = App.GetService<IAuthorizationManager>().GetUser();
            input.ApplyName = user.UserName;
            Shield shield = input.Adapt<Shield>();

            shield.CreatedTime = DateTimeOffset.Now;
            var newEntity = await _shieldRepository.InsertAsync(shield);

            return newEntity.Entity.Adapt<ShieldDto>();
        }

        /// <summary>
        /// 删除一条
        /// </summary>
        /// <param name="id"></param>
        public override async Task<bool> Delete(int id)
        {
            var shield = await _shieldRepository.FindAsync(id);

            //删除限制类型before时 更新车辆放行
            if (shield.ShieldType != ShieldType.After)
            {
                //种类为新申请或all时 修改车辆信息 放行 值（未删除 已审核）
                var cars = _carRepository
                  .Where(c => c.IsDeleted == false && c.IsPass == PassType.Yes && c.IsRelease == false && c.CarNumber.Contains(shield.ShieldNumber))
                  .AsNoTracking()   //取消attached
                  .Select(u => u.Adapt<Car>());

                foreach (Car car in cars)
                {
                    car.IsRelease = true;
                    car.UpdatedTime = DateTimeOffset.Now;
                    await _carRepository.UpdateAsync(car);
                }
            }

            await _shieldRepository.FakeDeleteAsync(shield);
            return true;
        }

        /// <summary>
        /// 查询一条
        /// </summary>
        /// <param name="id"></param>
        public override async Task<ShieldDto> Get(int id)
        {
            var person = await _shieldRepository
                .Where(x => x.Id == id)
                .FirstOrDefaultAsync();
            return person.Adapt<ShieldDto>();
        }
    }
}
